#!/usr/bin/python
# -*- coding: utf8 -*-

import re, time
from BeautifulSoup import BeautifulSoup
from Http_query import Http_query
from Web_parser import Web_parser
from Dater import Dater

class Auth(Http_query):
   u'''Must created and logined by master.
Then passed to by Search, Messanger and Checker.
'''
   def __init__(self):
      super(Auth, self).__init__()
      self.login    = 'alpha_tester'
      self.password = 'qwerty'
      self.opener = None

   def Login(self, login = None, password = None):
      if not login:
         login    = self.login
         password = self.password
      else:
         if not self.opener:
            self.opener = self.getOpener()
      url = u'http://dating.ru/auth.php'
      form = {
            u'come_back_url' :      u'aHR0cDovL2RhdGluZy5ydS9pbmRleC5waHA/',
            u'give_all_cookies':    u'',
            u'tip':                 u'',
            u'oid':                 u'',
            u'tcurl':               u'',
            u'login':               login,
            u'passwd':              password,
            u'button_auth_submit':  u'',
            u'level':               u'Low'
      }
      self.Post_form(url, form)

class Searcher(Http_query):
   def __init__(self):
      super(Searcher, self).__init__()
      self.re_info_by_link = re.compile(u'(?imu)http://dating\.ru/([a-z_0-9]+)/.+oid=([0-9]+)')
      self.re_offset = re.compile(u'(?imu)(?:http://dating.ru)?/search\.php\?offset=([0-9]+)&.+')
      self.soup = None
      self.opener = None

   def getDaters(self, count):
      daters     = []
      followed   = []
      more       = set()
      offset     = None
      while count:
         if len(more):
            while len(more):
               link = more.pop()
               m = self.re_offset.match(link)
               if m:
                  offset = int(m.group(1))
                  if not offset in followed:
                     break
               else:
                  print link
            else:
               break
            if offset:
               followed.append(offset)
            print u'======================'
            print u'Followed tabs: %s' % (u' '.join([str(a) for a in sorted(followed)]))
            html = self.Retrieve(link)
         else:
            html = self.Search()
         soup = self.Parse(html)
         newbies = self.Get_daters(soup)
         if len(newbies) < count:
            daters+= newbies
            count-= len(newbies)
            for a in self.Get_further_pages(soup):
               more.add(a)
         else:
            daters+= newbies[:count]
            count = 0
      if count:
         print count, u'daters not retrieved. No more :('
      return daters

   def Search(self):
      url = u'http://dating.ru/search.php'
      form = {
            u'search_type'     : u'',
            u'search_iam'      : u'M',
            u'search_lookfor'  : u'F',
            u'search_age_from' : u'18',
            u'search_age_to'   : u'22',
            u'city'            : u'101_6675_101',
            u'search_photo'    : u'checked',
            u'search_online'   : u'checked',
            u'search_wh'       : u'checked',
            u'submit.x'        : u'0',
            u'submit.y'        : u'0'
             }
      return self.Post_form(url, form, u'search.html')

   def Parse(self, html):
      if type(html) == str:
         html = html.decode('cp1251')
      if html:
         html = self.Remove_scripts(html)
         soup = BeautifulSoup(html)
         return soup
      else:
         return None

   def Remove_scripts(self, text):
      text = re.sub(u'(?imu)<script([ \r\n\t]|.)+?</script>', u'', text)
      text = text.replace(u'>', u'>\n')
      text = text.replace(u'align=""center', u'align="center"')
      text = text.replace(u'id="c_leader_out""', u'id="c_leader_out"')
      return text

   def Get_daters(self, soup):
      h1s = soup.findAll(u'h1')
      h1 = h1s[-1]
      table = h1.findNext(u'table', id = u'search_form')
      daters = []
      if table:
         tr = table.findChild(u'tr')
         while tr:
            strong = tr.findChild(u'strong', u'enlarge')
            if strong and strong.string:
               d = Dater()
               #d.real_name = strong.string.strip()
               anchor = strong.parent
               if anchor:
                  m = self.re_info_by_link.match(anchor[u'href'])
                  if m:
                     d.login, d.oid = m.groups()
               daters.append(d)
            tr = tr.findNextSibling(u'tr')
      return daters

   def Get_further_pages(self, soup):
      table = soup.find(u'table', u'pager')
      cur_td = table.find(u'td', u'current_page')
      tds = cur_td.findAllNext(u'td', u'page')
      links = []
      ids = []
      for td in tds:
         anchor = td.find(u'a')
         if anchor:
            id = int(self.re_offset.match(anchor['href']).group(1))
            #print u'%d' % (id)
            links.append(self.Cure_link(anchor['href']))
         else:
            print u'No anchor'
      return links

   def Cure_link(self, link):
      if link.startswith(u'/'):
         link = u'http://dating.ru%s' % (link)
      return link

class Messanger(Http_query):
   def __init__(self):
      super(Messanger, self).__init__()
      self.auth = None

   def setAuth(self, auth):
      self.auth = auth

   def Send_message(self, oid, message):
      url = u'http://dating.ru/message.php'
      form = {
         u'oid'      : oid,
         u'action'   : u'post',
         u'dopost'   : u'1',
         u'check'    : u'',
         u'tcurl'    : u'',
         u'message'  : message,
         u'submit_b' : u'',
         u'submit_b.x': u'0',
         u'submit_b.y': u'0'
      }
      self.auth.Post_form(url, form, 'tester.html')

   def Be_polite(self):
      time.sleep(2)

class Checker(Http_query):
   def __init__(self):
      super(Checker, self).__init__()
      self.auth = None

   def setAuth(self, auth):
      self.auth = auth

   def checkMessages(self):
      link = 'http://dating.ru/messages.php'
      html = self.auth.Retrieve(link)
      html = self.Remove_scripts(html)
      soup = BeatifulSoup(html)
      chatters = self.getChatters(soup)

   def getChatters(self, soup):
      user_table = soup.findAll(u'table', u'form_data', id=u'messages_users')
      print len(user_table)

import codecs
def main():
   content = codecs.open(u'search.html', 'r', 'cp1251').read()
   Search_parser().Parse(content)

if __name__ == '__main__':
   main()